package com.security.common;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Service;

/**
 * 系统资源访问决策器
 * 获取访问url对应的所有权限
 * @author rui
 */
@Service
public class SecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
	//有权限校验的URL集合
	private Map<String, List<ConfigAttribute>> mp;
	private RequestMatcher requestMatcher;
	
	/**
	 * 初始化所有资源所需要的权限
	 */
	public SecurityMetadataSource(){
		this.mp = new HashMap<String, List<ConfigAttribute>>();
		List<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
		ConfigAttribute cb = new SecurityConfig("ROLE_ADMIN"); // 构造一个权限(角色)
		ConfigAttribute cbUser = new SecurityConfig("ROLE_USER"); // 构造一个权限(角色)
		ConfigAttribute cbManager = new SecurityConfig("ROLE_MANAGER"); // 构造一个权限(角色)
		list.add(cb);
		list.add(cbUser);
		list.add(cbManager);
		mp.put("/index", list);
		mp.put("/login", list);
	}
	/**
	 * 获取访问的地址是否是决策器中需要校验的地址，如果是则返回待决策权限集合
	 * return Collection<ConfigAttribute> 访问的资源所需要的权限集合
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object arg0)
			throws IllegalArgumentException {
		FilterInvocation filterInvocation = (FilterInvocation)arg0;
		//用户待访问的资源地址
		String requestUrl = filterInvocation.getRequestUrl();
		Iterator<String> iter = this.mp.keySet().iterator();
		while (iter.hasNext()){
			requestMatcher = new AntPathRequestMatcher(requestUrl);
		    if(requestMatcher.matches(filterInvocation.getHttpRequest())) {
		        return mp.get(requestUrl);
		    }
		}
		return null;
	}
	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}
	@Override
	public boolean supports(Class<?> arg0) {
		return true;
	}
}
